//
//
////simefun 不能继承任何对象！！！重要


import (Os) in "java/com/faros/lib/Os";
import (App) in "App";
//
//
//// 预定义的中文名字和姓氏列表
var chineseFirstNames = ([
    "子涵", "宇轩", "欣怡", "晨曦", "梓涵", "诗涵",
    "浩然", "雨婷", "嘉诚", "思琪", "俊轩", "梦洁",
    "子淳", "子豪", "梓萱", "思涵", "梓涵", "若兮",
    "晨浩", "清扬", "恒古", "老五", "老四", "老三",
    "子贡", "子清", "子淳", "老六", "鹏来", "老二","东来","西来","北城"
]);

var chineseLastNames = ([
    "李", "王", "张", "刘", "陈", "杨",
    "赵", "黄", "周", "吴", "徐", "孙",
    "胡", "朱", "高", "林", "何", "郭",
    "马", "罗", "梁", "宋", "郑", "谢",
    "韩", "唐", "冯", "于", "董", "萧",
    "程", "曹", "袁", "邓", "许", "傅",
    "沈", "曾", "彭", "吕", "苏", "卢",
    "蒋", "蔡", "贾", "丁", "魏", "薛",
    "叶", "阎", "余", "潘", "杜", "戴",
    "夏", "钟", "汪", "田", "任", "姜",
    "范", "方", "石", "姚", "谭", "廖",
    "邹", "熊", "金", "陆", "郝", "孔",
    "白", "崔", "康", "毛", "邱", "秦",
    "江", "史", "顾", "侯", "邵", "孟",
    "龙", "万", "段", "漕", "钱", "汤",
    "尹", "黎", "易", "常", "武", "乔",
    "贺", "赖", "龚", "文"
]);
//
//
//
//// 生成随机索引
//int  getRandomIndex( var arr) {
//    return random(0,arr.size());
//}
//
//// 生成随机中文姓名
//string randomCnName() {
//    int randomLastNameIndex = getRandomIndex(this.chineseLastNames);
//    int randomFirstNameIndex = getRandomIndex(this.chineseFirstNames);
//    string lastName = this.chineseLastNames[randomLastNameIndex];
//    string firstName = this.chineseFirstNames[randomFirstNameIndex];
//    return lastName+firstName;
//}
//
//
//
//移除后缀
string rmSuffix(string file){
    int pos = strsrch(file,".");
    println("位置"+pos);
//    file = file.subString(0,pos);
    return file;
}

static string hashCode(object ob){
    return Os::hashCode(ob);
}

static string baseName(object ob){
    return Os::className(ob);
}

static object make(string className){

        var ob = new(className);
        ob.set("hasId",hashCode(ob));
        ob.set("fileAddr",baseName(ob)+"#"+hashCode(ob));
        //是否初始化过,默认不能初始化
        ob.set("isLoad",0);
        ob.create();
        //    ob.load();
        println( "make: "+className );
        App::objs[hashCode(ob)] = ob;
        return ob;


}

//在已加载的对象表中查找
static object findObject(string s){
    foreach(k in App::objs){
        if( !App::objs[k] ) continue;//集合中，可能有对象在任意时刻被销毁..
        if( strsrch( App::objs[k].query("fileAddr"),s) > -1 ){
            return App::objs[k];
        }
    }
    return 0;
}



//
//
///*
//   1、对象池中找  s中不能带地址
//   2、找不到就new
//*/
static object loadObject(string s){
    object ob;
    if( (ob=findObject(s)) ){
        return ob;
    }



    println("make "+s);
     return make(s);


}

//
//获取所有已经加载的对象 返回的是map结构
static map objects(){
   return App::objs;
}

//是否是玩家
static number userp(object ob){
   if( ob.query("isUser") ){
         return 1;
   }
   return 0;
}



static var users(){

  var users = ([]);

 foreach( k in App::objs ){
    if( App::objs[k].query("isUser") ){
        users+=App::objs[k];
    }
  }
  return users;
}


static number present(var dest, object env){

    object *obs = allInventory(env);
    foreach( ob in obs ){
        if( dest in ob.query("ids") ){
            return ob;
        }
    }
    return 0;
}
static var isLoginByNid(string nid){

    var users = users();

    foreach( k in users ){
      println( fmt("原nid(%s) ,新nid(%s)",users[k].query("netAgentId"),nid));
        //如果掉线 netAgentId肯定就没有了
        if( users[k].query("netAgentId") == nid ){
            return 1;
        }
    }
    return 0;

}
//是否还连接着
static var netConn(string nid){

    var users = users();
    foreach( k in users ){
        //如果掉线 netAgentId肯定就没有了
        if( users[k].query("netAgentId") == nid ){
            return users[k];
        }
    }
    return 0;
}




static object findUserOf(string nid){
         var users = users();
        foreach( k in users ){
            //如果掉线 netAgentId肯定就没有了
            if( users[k].query("netAgentId") == nid ){
                return users[k];
            }
        }
        return 0;
}

//查找玩家 包括断线和没有断线的
static object findUser(string id){
    var users = users();
    foreach( k in users ){
        if( users[k].id() == id ){
            return users[k];
        }
    }
    return 0;
}

////find_object() - 通过文件名（file_name()）查找对象
//object findObject(string fileAddr){
//
//  var data = filterMap(TaskInput::allObjs,(k,v)->{
//       if( funcExists(v,"query") && v.query("file_addr") == fileAddr ) return true;
//    });
//    if( data ) return data;
//    return 0;
//}
//
static string fileName(object ob){

    return ob.query("fileAddr");


}
//
//
//var filterMap(var mapData,var func){
//    var keys = keys(mapData);
//    for(int i;i < keys.size();i++){
//        var e = mapData[keys[i]];
//        if( func(keys[i],e) ){
//            return e;
//        }
//    }
//    return 0;
//}

//过滤数组，返回新数组,原数组不变
static var filterArray(var ele,var func){

    if( !arrayp(ele) ) return 0;
    var* ret = ([]);
    foreach( e in ele ){
        if( func(e) ){
            ret+=e;
        }
    }
    return ret;
}

//
static var tellObject(object user,string msg){
    if( !user ){
        return 0;
    }
    if( !user.query("isUser") ){
//        println(baseName(user)+" 不是玩家，不能调用tellObject");
        return 0;
    }

    if( isDisNetConn(user) ){//网络是否断开了..

//        println( fmt("%s(%s) 的网络已断开，不能调用tellObject!",user.query("name"),fileName(user)) );

        return 0;
    }

    string nid = user.query("netAgentId");
    object channel = user.query("netChannel");
//    varDump(msg+""+"\n");
    channel.send(nid,msg);

}


//网络是否断开
static number isDisNetConn(object ob){
    if( !ob.query("netAgentId") || !ob.query("netChannel") ) return 1;
    return 0;
}


//通知环境里的人
static var tellEnv(object env,string msg){
    object *obs;
    if( !env ) return 0;

    obs = allInventory(env);
    if( !obs ) return 0;
    foreach( ob in obs ){
        if( ob.query("isUser") ){
            tellObject(ob,msg);
        }
    }
}

static number notifyFail(string s){

}

static number notifyOk(string s){

}



//
////返回所有内容对象
static var allInventory( object ob ){
    //这句是为了外部访问时报错 保证返回一个空数组
    if( !ob.query("inventoryLists") ) return ([]);
    return ob.query("inventoryLists");
}
//

//
//
static number rmInventory(object env, var ob){
     var d = env.query("inventoryLists");
     d -= ob;
     return 1;
}
//
////void move_object( object | string dest );
////src 源对象
static number moveObject( object src, var dest ){
    object ob,env;
    if(stringp(dest)){
        ob = loadObject(dest);
    }else{
        ob = dest;
    }

    if(!ob) {//对象加载出问题
       println("对象加载错误!");
       return 1;
    }

    //如果自己当前存在于环境 就移出去

    env  = environment(src);

    if( objectp(env) ){
        println(src.query("name")+" 移动前环境<"+env.query("short")+">");
        env.removeInventory(src);
//        rmInventory(env,src);
    }else{
        println(src.query("name")+" 移动前环境<虚空>");
    }


    //不存实体，只存ID
    var d = ob.query("inventoryLists");
    if(!d ){
        ob.set("inventoryLists",([src]));
    }else{
        d+=src;
    }

    println("当前环境"+baseName(ob));

     src.set("currEnv",ob);
     return 1;

}

static object environment( object ob  ){


    return ob.query("currEnv")?ob.query("currEnv"):0;
}
//
//
//
static var parseCommand(var msg){
    var instr,argv;
    var cmd;
    if( strsrch(msg," ") > 0 ){
        instr = explode(msg," ");
        //跳过第一位，取多少位
        //argv 是参数内容
         argv = implode(subcut(instr,1,sizeof(instr) )," ");
         cmd = instr[0];
    }else{
        argv="";
        cmd = msg;
    }
    return ([cmd,argv]);
}
//
static number command(object ob,string msg){

//    string cmd,argv;
     (cmd,argv) = parseCommand(msg);
    println("command 当前的指令是-->"+cmd);

     if( !App::cmds[cmd] ){
         println("command 执行时找不到指令-->"+cmd);
         return 0;
     }

     App::cmds[cmd].main(ob,argv);
}


static var testOk(var s){
    println("内置函数库的 "+s);
}

//异步调用对象方法
static var callOut(object ob,string funcName, number t, var *args){
//    object ob = args[0];//ob
//    string funcName = args[1];//对象的方法名称
//    number t = args[2];//延迟多久开始执行 单位:ms
    App::taskMgr.submitDelayedTask(t,()->{
        return  callInsMethod(ob,funcName,args);
    },(e)->{
        println("异步方法执行完成...");
        println(e);
    });
}

//计划任务
static number addSchedulerTask(number delay,string task_name,string cron){
     // "*/5 * * * * *,1 adm/xxx/Xx testCron 参数1";
     (crons,callAbleStr)    =   explode(cron,",");
     string callParam       =   explode(callAbleStr," ");
     ( methodTye,cls,methodName ) = callParam;
     string* args = subcut(callParam,3,sizeof(callParam));
     println(fmt("调用信息 %s %s %s",methodTye,cls,methodName));

    //1 调用静态方法
    App::cronScheduler.putTask(delay,task_name,crons,()->{ callStaticMethod(cls,methodName,args);});

}
//删除计划任务
static number removeSchedulerTask(string taskId){
     App::cronScheduler.removeTask(taskId);
}

